package com.vmock.base.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.vmock.base.core.response.IMockResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.env.RandomValuePropertySource;
import org.springframework.util.StringUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Slf4j
public class ResponseUtils {

    /**
     *
     */
    private static final String PREFIX = "random.";

    /**
     * 处理结果
     *
     * @param request
     * @param mockResponse
     */
    public static void doParseContent(String request, IMockResponse mockResponse) {
        try {
            //参数集合
            Map<String, String> params = new HashMap<>();
            transParams(request, params);

            //返回值
            String content = mockResponse.getContent();
            // 匹配方式${XXX}
            Pattern p = Pattern.compile("\\$\\{(.*?)}");
            Matcher matcher = p.matcher(content);
            // 解析随机值对象
            RandomValuePropertySource randomValuePropertySource = new RandomValuePropertySource();
            // 处理匹配到的值
            while (matcher.find()) {
                String key = matcher.group();
                String param = key.replace("${", "").replace("}", "");
                // 仅处理random.开头的配置
                if (param.startsWith(PREFIX)) {
                    Object rs = randomValuePropertySource.getProperty(param);
                    content = content.replace(key, String.valueOf(rs));
                } else {
                    //处理其他
                    String val = params.get(param);
                    content = content.replace(key, val == null ? "" : val);
                }
            }
            mockResponse.setContent(content);
        } catch (Exception e) {
            log.error("填充参数异常", e);
        }
    }

    /**
     * 转换参数
     * @param request
     * @param params
     */
    private static void transParams(String request, Map<String, String> params) {
        JSONObject jsonObject = JSON.parseObject(request);
        Map<String, String> paramMap = jsonObject.getObject("params", Map.class);
        if (paramMap.size() == 0) {
            // body
            String body = jsonObject.getString("body");
            if (StringUtils.hasLength(body)) {
                parseBody(params, JSON.parseObject(body), "");
            }
        } else {
            parseParams(params, paramMap, "");
        }
    }

    /**
     * 解析body参数
     * @param params
     * @param body
     * @param key
     */
    private static void parseBody(Map<String, String> params, JSONObject body, String key) {
        for (Map.Entry<String, Object> entry : body.entrySet()) {
            Object obj = entry.getValue();
            if (obj instanceof JSONArray) {
                JSONArray jsonArray = (JSONArray) obj;
                for (int i = 0; i < jsonArray.size(); i++) {
                    Object object = jsonArray.get(i);
                    if ((object instanceof JSONArray || object instanceof JSONObject)) {
                        //解析
                        JSONObject jsonObject = (JSONObject) jsonArray.get(i);
                        Map<String, String> data = new HashMap<>();
                        dealJsonObj(jsonObject, data);
                        parseParams(params, data, (StringUtils.hasLength(key) ? key + "." + entry.getKey() : entry.getKey()) + "[" + i + "]");
                    } else {
                        params.put((StringUtils.hasLength(key) ? key + "." + entry.getKey() : entry.getKey()) + "[" + i + "]", String.valueOf(object));
                    }
                }
            } else if (obj instanceof JSONObject) {
                //解析
                JSONObject jsonObject = (JSONObject) entry.getValue();
                Map<String, String> data = new HashMap<>();
                dealJsonObj(jsonObject, data);
                parseParams(params, data, StringUtils.hasLength(key) ? key + "." + entry.getKey() : entry.getKey());
            } else {
                params.put(StringUtils.hasLength(key) ? key + "." + entry.getKey() : entry.getKey(), String.valueOf(entry.getValue()));
            }
        }
    }

    /**
     * 分析参数
     *
     * @param params
     * @param paramMap
     * @param key
     */
    public static void parseParams(Map<String, String> params, Map<String, String> paramMap, String key) {
        // get all param
        for (Map.Entry<String, String> entry : paramMap.entrySet()) {
            if (isJson(entry.getValue())) {
                Object obj = JSON.parse(entry.getValue());
                if (obj instanceof JSONArray) {
                    JSONArray jsonArray = (JSONArray) obj;
                    for (int i = 0; i < jsonArray.size(); i++) {
                        Object object = jsonArray.get(i);
                        if ((object instanceof JSONArray || object instanceof com.alibaba.fastjson.JSONObject)) {
                            //解析
                            JSONObject jsonObject = (JSONObject) jsonArray.get(i);
                            Map<String, String> data = new HashMap<>();
                            dealJsonObj(jsonObject, data);
                            parseParams(params, data, (StringUtils.hasLength(key) ? key + "." + entry.getKey() : entry.getKey()) + "[" + i + "]");
                        } else {
                            params.put((StringUtils.hasLength(key) ? key + "." + entry.getKey() : entry.getKey()) + "[" + i + "]", String.valueOf(object));
                        }
                    }
                } else {
                    //解析
                    JSONObject jsonObject = JSON.parseObject(entry.getValue());
                    Map<String, String> data = new HashMap<>();
                    dealJsonObj(jsonObject, data);
                    parseParams(params, data, StringUtils.hasLength(key) ? key + "." + entry.getKey() : entry.getKey());
                }
            } else {
                params.put(StringUtils.hasLength(key) ? key + "." + entry.getKey() : entry.getKey(), entry.getValue());
            }
        }
    }

    /**
     * 处理JSONOBJECt
     *
     * @param jsonObject
     * @param data
     */
    private static void dealJsonObj(JSONObject jsonObject, Map<String, String> data) {
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            String val = "";
            if (entry.getValue() instanceof JSONArray || entry.getValue() instanceof JSONObject) {
                val = JSON.toJSONString(entry.getValue());
            } else {
                val = String.valueOf(entry.getValue());
            }
            data.put(entry.getKey(), val);
        }
    }

    /**
     * 判断是否JSON字符串
     *
     * @param content
     * @return
     */
    public static boolean isJson(String content) {
        try {
            Object obj = JSON.parse(content);
            if (obj instanceof JSONArray || obj instanceof JSONObject) {
                return true;
            } else {
                return false;
            }

        } catch (Exception e) {
            return false;
        }
    }

}
